package list;


public class DirtyLinkedList extends AbstractList {
	private Node first;

	public DirtyLinkedList() {
	}

	public DirtyLinkedList(Object[] objects) {
		super(objects);
	}

	@Override
	public void add(int index, Object object) {
		if (first == null) {
			first = new Node(object);
			size++;
			return;
		}

		if (index == 0) {
			addFirst(object);
			return;
		}
		if (index == size) {
			addLast(object);
			return;
		}

		if (index > size) {
			throw new IndexOutOfBoundsException();
		}

		Node node = new Node(object);
		Node current = first;
		Node previous = null;
		for (int i = 0; i < index; i++) {
			previous = current;
			current = current.next;
		}
		previous.next = node;
		node.next = current;
		size++;
	}

	public void addFirst(Object object) {
		Node node = new Node(object);
		node.next = first;
		first = node;
		size++;
	}

	public void addLast(Object object) {
		Node current = first;
		Node node = new Node(object);
		for (int i = 0; i < size - 1; i++) {
			current = current.next;
		}
		current.next = node;
		size++;
	}

	@Override
	public void clear() {
		first = null;
	}

	@Override
	public boolean contains(Object object) {
		Node current = first;
		boolean result = false;
		for (int i = 0; i < size; i++) {
			if (current.element.equals(object)) {
				result = true;
				break;
			}
			current = current.next;
		}
		return result;
	}

	@Override
	public Object get(int index) {
		Node current = first;
		for (int i = 0; i < index; i++) {
			current = current.next;
		}
		return current.element;
	}

	@Override
	public void remove(int index) {
		Node current = first;
		Node previous = null;

		if (index > size - 1) {
			throw new IndexOutOfBoundsException();
		}

		if (index == 0) {
			first = first.next;
			size--;
			return;
		}

		if (index == size - 1) {
			for (int i = 0; i < size - 1; i++) {
				current = current.next;
			}
			current.next = null;
			size--;
			return;
		}

		for (int i = 0; i < index; i++) {
			previous = current;
			current = current.next;
		}
		previous.next = current.next;
		size--;
	}

	@Override
	public void set(int index, Object object) {
		Node current = first;
		for (int i = 0; i < index; i++) {
			current = current.next;
		}
		current.element = object;
	}

	@Override
	public int lastIndexOf(Object object) {
		int index = -1;
		Node current = first;
		for (int i = 0; i < size; i++) {
			if (current.element.equals(object)) {
				index = i;
			}
			current = current.next;
		}
		return index;
	}

	public String toString() {
		if (first == null) {
			return null;
		}
		StringBuilder sb = new StringBuilder("[");
		Node current = first;
		for (int i = 0; i < size; i++) {
			sb.append(current.element).append(",");
			current = current.next;
		}
		sb.replace(sb.length() - 1, sb.length(), "]");
		sb.append(size);
		return sb.toString();
	}
}
